package cn.cellcom.agent.util;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.StringUtils;

import redis.clients.jedis.Jedis;

/**
 * Redis配置工具类
 * 
 */
public class RedisHelper {

	private String host = "127.0.0.1";

	private int port = 6379;

	private int index = -1;

	public static void main(String[] args) {
		RedisHelper r = new RedisHelper("127.0.0.1", 6379, 1);
		for (int i = 0; i < 1234; i++) {
			System.out.println(r.incr("aaa"));
		}
		System.out.println("");
	}

	/**
	 * redisAddr格式：10.169.108.252:26379,10.169.142.54:26379
	 * 
	 * @param redisAddr
	 * @return
	 */
	public RedisHelper(String host, int port, int index) {
		this.host = host;
		this.port = port;
		this.index = index;
	}

	public Jedis getJedis() {
		// return RedisUtil.getInstance(redisAddr, index).getJedis();
		Jedis jedis = new Jedis(host, port);
		jedis.select(index);
		jedis.connect();
		return jedis;
	}

	/**
	 * 获取key的值，如果没有传入jedis则进行自己创建以及关闭
	 * 
	 * @param jedis
	 * @param key
	 * @return
	 */
	public String getStringWithJedis(Jedis jedis, String key) {
		boolean localJedis = false;
		if (jedis == null) {
			jedis = getJedis();
			localJedis = true;
		}
		try {
			if (key != null) {
				return jedis.get(key);
			}
			return null;
		} finally {
			if (jedis != null && localJedis)// 本地创建的则
				jedis.disconnect();
		}
	}

	// //////////////////////////////////////////以下为基础操作/////////////////////////////////////////////////
	public boolean lockAMinute(String key) {
		return lock(key, 60);
	}

	public boolean lock(String key, int expire) {
		Jedis jedis = getJedis();
		try {
			long i = jedis.setnx(key, "lock");
			if (i == 1) {
				jedis.expire(key, expire);
				return true;
			}
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
		return false;
	}

	/**
	 * 将对象存入Redis
	 * 
	 * @param key
	 * @param obj
	 * @return
	 */
	public String putString(String key, String string) {
		Jedis jedis = getJedis();
		try {
			jedis.set(key, string);
			return string;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * @param key
	 * @param string
	 * @param seconds
	 * @return
	 */
	public String putAndExpireString(String key, String string, int seconds) {
		Jedis jedis = getJedis();
		try {
			jedis.setex(key, seconds, string);
			return string;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 设置key的expire time
	 * 
	 * @param key
	 * @param seconds
	 */
	public void expire(String key, int seconds) {
		Jedis jedis = getJedis();
		try {
			jedis.expire(key, seconds);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 存放一个对象
	 * 
	 * @param key
	 * @param object
	 * @return
	 */
	public <T> T putObject(String key, T object) {
		Jedis jedis = getJedis();
		try {
			jedis.set(key.getBytes(), SerializableUtils.serialize(object));
			return object;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 
	 * @param <T>
	 * @param key
	 * @param object
	 * @param seconds
	 * @return
	 */
	public <T> T putObject(String key, T object, int seconds) {
		Jedis jedis = getJedis();
		try {
			jedis.setex(key.getBytes(), seconds, SerializableUtils.serialize(object));
			return object;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 获取一个对象
	 * 
	 * @param key
	 * @param t
	 * @return
	 */
	public <T> T getObject(String key, Class<T> t) {
		T result = null;
		Jedis jedis = getJedis();
		try {
			byte[] vl = jedis.get(key.getBytes());
			if (vl == null) {
				return null;
			}
			result = SerializableUtils.unserialize(vl, t);
			return result;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 从Redis中删除对象
	 * 
	 * @param key
	 */
	public Object remove(String key) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				Object obj = get(key);
				if (obj != null) {
					jedis.del(key);
					return obj;
				}
			}
			return null;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 从Redis中查询KEY
	 * 
	 * @param key
	 * @return
	 */
	public String getString(String key) {
		return this.getStringWithJedis(null, key);
	}

	/**
	 * 多个key查询
	 * 
	 * @param keys
	 * @return
	 */
	public List<String> mgetString(String[] keys) {
		Jedis jedis = getJedis();
		try {
			if (keys != null) {
				return jedis.mget(keys);
			}
			return null;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 获取key中的MAP的filed对应的Integer值
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return
	 */
	public Map<String, String> hgetAll(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.hgetAll(key);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	public Long hputString(String key, String field, String value) {
		Jedis jedis = getJedis();
		if (value == null) {
			value = "";
		}
		try {
			return jedis.hset(key, field, value);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	public String hgetString(String key, String field) {
		Jedis jedis = getJedis();
		try {
			return jedis.hget(key, field);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	public boolean hexists(String key, String field) {
		Jedis jedis = getJedis();
		try {
			return jedis.hexists(key, field);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	public Set<String> hkeys(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.hkeys(key);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 从Redis中删除对象（使用hputString后，可调用此方法进行删除）
	 * 
	 * @param key
	 */
	public void hDel(String key, String... field) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				jedis.hdel(key, field);
			}
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 从Redis中删除对象（使用hputString后，可调用此方法进行删除）
	 * 
	 * @param key
	 */
	public void hRemove(String key) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				jedis.del(key);
			}
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 将对象存入Redis
	 * 
	 * @param key
	 * @param obj
	 * @return
	 */
	public Integer putInteger(String key, Integer number) {
		Jedis jedis = getJedis();
		try {
			jedis.set(key, String.valueOf(number));
			return number;
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 从Redis中查询KEY
	 * 
	 * @param key
	 * @return
	 */
	public Integer getInteger(String key) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				String vl = jedis.get(key);
				return StringUtils.isBlank(vl) ? 0 : Integer.parseInt(vl);
			}
			return null;
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 获取证书,如果不存在则返回0
	 * 
	 * @param key
	 * @return
	 */
	public Integer getInteger0(String key) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				String vl = jedis.get(key);
				return StringUtils.isBlank(vl) ? 0 : Integer.parseInt(vl);
			}
			return 0;
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 从Redis中查询KEY
	 * 
	 * @param key
	 * @return
	 */
	public Object get(String key) {
		Jedis jedis = getJedis();
		try {
			if (key != null) {
				return jedis.get(key);
			}
			return null;
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 获取所有的key集合
	 * 
	 * @return
	 */
	public Set<String> keySet() {
		Jedis jedis = getJedis();
		try {
			return jedis.keys("*");
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 清空缓存数据
	 */
	public void clear() {
		Jedis jedis = getJedis();
		try {
			Set<String> keySet = keySet();
			for (Iterator<String> iterator = keySet.iterator(); iterator.hasNext();) {
				String key = iterator.next();
				jedis.del(key);
			}
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 累加
	 * 
	 * @param key
	 * @return
	 */
	public Long incr(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.incr(key);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 递减
	 * 
	 * @param key
	 * @return
	 */
	public Long decr(String key, long x) {
		Jedis jedis = getJedis();
		try {
			return jedis.decrBy(key, x);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 增加X
	 * 
	 * @param key
	 * @return
	 */
	public Long incr(String key, long x) {
		Jedis jedis = getJedis();
		try {
			return jedis.incrBy(key, x);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 获取部分key
	 * 
	 * @param prefix
	 * @return
	 */
	public Set<String> keys(String prefix) {
		Jedis jedis = getJedis();
		try {
			return jedis.keys(prefix);
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 删除可以下的某个field指
	 * 
	 * @param key
	 * @param field
	 * @return
	 */
	public boolean hdel(String key, String field) {
		Jedis jedis = getJedis();
		try {
			jedis.hdel(key, field);
			return true;
		} finally {
			if (jedis != null)
				jedis.disconnect();
		}
	}

	/**
	 * 将一组字符串写入redis中的set
	 * 
	 * @param key
	 * @param strings
	 */
	public void sadd(String key, String... strings) {
		Jedis jedis = getJedis();
		try {
			jedis.sadd(key, strings);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 获取指定集合
	 * 
	 * @param key
	 * @return
	 */
	public Set<String> sMembers(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.smembers(key);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 删除指定key
	 * 
	 * @param key
	 */
	public void delkey(String key) {
		Jedis jedis = getJedis();
		try {
			jedis.del(key);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 
	 * @param key
	 * @return
	 */
	public long hlen(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.hlen(key);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	/**
	 * 将字符串list集合写入redis的list
	 * 
	 * @param key
	 * @param list
	 */
	public void lpush(String key, List<String> list) {
		if (list == null) {
			return;
		}
		Jedis jedis = getJedis();
		try {
			jedis.lpush(key, list.toArray(new String[list.size()]));
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}

	public List<String> lrange(String key) {
		Jedis jedis = getJedis();
		try {
			return jedis.lrange(key, 0, -1);
		} finally {
			if (jedis != null) {
				jedis.disconnect();
			}
		}
	}
}
